package cn.com.infcn.monitor.core;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;

import cn.com.infcn.monitor.bean.IFCResponseBean;
import cn.com.infcn.monitor.util.IFCFileUtils;
import cn.com.infcn.monitor.util.IFCMonitorConstanst;
import cn.com.infcn.monitor.util.IFCMonitorUtils;
import cn.com.infcn.monitor.util.MonitorType;

public class MonitorProcessor {

	private HttpServletRequest request;
	private HttpServletResponse response;

	public MonitorProcessor(HttpServletRequest request, HttpServletResponse response) {
		this.request = request;
		this.response = response;
	}

	public void processor() throws Exception {
		// 设置HTTP相应头
		setHeader();
		
		String prefix=request.getContextPath()+"/"+IFCMonitorConstanst.MONITORING_SERVLET_PATH_NAME;	//projectName/IFCMonitorServlet/
		String str = request.getRequestURI().replace(prefix, "");		
		
		if("".equals(str) || "/".equalsIgnoreCase(str)) {
			String monitorDate = request.getParameter("monitorDate");
			if(IFCMonitorUtils.isNotBlank(monitorDate)){
				historyMonitor();
			}else{
				realTimeMonitor();
			}
		}else if(("/"+IFCMonitorConstanst.MONITOR_TYPE).equalsIgnoreCase(str) 
				|| ("/"+IFCMonitorConstanst.MONITOR_TYPE+"/").equalsIgnoreCase(str)){
			monitorType();
		}else{
			api();
		}

	}

	private void historyMonitor() throws Exception {
		String type = request.getParameter("type") == null ? "" : request.getParameter("type");
		String intervalVal = request.getParameter("interval");
		int interval = validateInterval(intervalVal);
		
		String[] typeArr = type.split(",");
		Set<String> typeSet = array2set(typeArr);
		String monitorDate = request.getParameter("monitorDate");
		//判断日志是否为空
		if (IFCMonitorUtils.isNotBlank(monitorDate)) {
			if (monitorDate.indexOf('-') == -1) {
				monitorDate = monitorDate + "-" + monitorDate;
			}
			String[] dates = monitorDate.split("-");
			if (validateDate(dates[0]) && validateDate(dates[1])) {
				if (typeSet.size()==0 || validateType(typeSet)) {
					if(typeSet.contains(MonitorType.ALL.getName())){
						typeSet = IFCMonitorUtils.getDefaultMonitorType(typeSet);
					}
					// 读取指定时间段的监控信息
					String json = IFCFileUtils.readerMonitorInfo(dates[0], dates[1], typeSet, interval);
					response(json);
				}else{
					responseTypeError();
				}
			} else {
				// error
				responseMonitorDateError();
			}
		}else{
			// error
			responseMonitorDateError();
		}
	}

	private void realTimeMonitor() throws Exception {
		String type = request.getParameter("type") == null ? "" : request.getParameter("type");
		String[] typeArr = type.split(",");
		Set<String> typeSet = array2set(typeArr);
		if (IFCMonitorUtils.isNotBlank(type) && validateType(typeSet)) {
			// 实时查询
			// 获取监控信息
			if(typeSet.contains(MonitorType.ALL.getName())){
				typeSet = IFCMonitorUtils.getDefaultMonitorType(typeSet);
			}
			
			IFCResponseBean result = MonitorCore.getIFCResponseBean(typeSet);

			// 转json信息
			String json = JSON.toJSONString(result);

			// 返回信息
			response(json);
		}else{
			responseTypeError();
		}
	}
	
	private void monitorType() throws Exception{
		
		Set<String> openType = IFCMonitorUtils.getDefaultMonitorType();
		List<String> allType = IFCMonitorUtils.getAllMonitorTypeList(); 
		List<String> staticType = IFCMonitorUtils.getAllMonitorTypeList();
		for (String s : openType) {
			staticType.remove(s);
		}
		staticType.remove(MonitorType.ALL.getName());
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("openType", IFCMonitorUtils.getDefaultMonitorType());
		map.put("allType",allType); 
		map.put("staticType",staticType); 
		
		String json = JSON.toJSONString(map);
		response(json);
	}
	
	private void api() throws Exception{
		Map<String, Object> map = new HashMap<String, Object>();
		
		Map<String, String> apiUrl = new HashMap<String, String>();
		apiUrl.put("http://ip:port/xxx/IFCMonitorServlet?type=all", "实时获取监控信息");
		apiUrl.put("http://ip:port/xxx/IFCMonitorServlet?monitorDate=201610011200-201610011300", "获取历史监控信息");
		apiUrl.put("http://ip:port/xxx/IFCMonitorServlet?monitorDate=201610011200-201610011300&type=cpu", "获取历史监控cpu的信息");
		apiUrl.put("http://ip:port/xxx/IFCMonitorServlet?monitorDate=201610011200-201610011300&type=cpu,sys,mem&interval=2", "获取历史监控cpu的信息,interval时间间隔数");
		apiUrl.put("http://ip:port/xxx/IFCMonitorServlet/monitorType", "监控类型");
		
		map.put("responseMsg", "访问地址错误！");
		map.put("apiUrl", apiUrl);
		
		String json = JSON.toJSONString(map);
		response(json);
	}

	private void setHeader() {
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/json; charset=utf-8");
		response.setHeader("Access-Control-Allow-Origin", "*");
	}

	/**
	 * 响应用户数据
	 * 
	 * @param json
	 * @throws IOException
	 */
	private void response(String json) throws IOException {
		PrintWriter out = response.getWriter();
		out.write(json);
	}

	/**
	 * 验证请求类型
	 * 
	 * @param type
	 * @return
	 * @throws IOException
	 */
	private boolean validateType(Set<String> types) throws IOException {
		boolean flag = true;
		List<String> monitorTypeList = IFCMonitorUtils.getAllMonitorTypeList();
		if(types!=null && types.size()>0){
			for (String t : types) {
				if (IFCMonitorUtils.isNotBlank(t) && !monitorTypeList.contains(t)) {
					flag = false;
				}
			}
		}
		return flag;
	}
	
	/**
	 * 验证时间间隔，如果小于等于1或者参数错误，都按照时间间隔1分钟计算
	 * @param interval
	 * @return
	 */
	private int validateInterval(String interval) {
		int result = 1;
		if(interval != null){
			try {
				result = Integer.parseInt(interval);
				if(result<=1){
					result = 1;
				}
			} catch (NumberFormatException e) {
			}
		}
		return result;
	}
	
	/**
	 * 响应监控类型格式错误
	 * @throws Exception
	 */
	private void responseTypeError() throws Exception{
		List<String> monitorTypeList = IFCMonitorUtils.getAllMonitorTypeList();
		
		IFCResponseBean result = new IFCResponseBean();
		result.setResponseCode(IFCMonitorConstanst.MONITOR_RESPONSE_CODE_ERROR);
		result.setResponseMsg("type 参数异常！参数应为：" + monitorTypeList.toString());
		String json = JSON.toJSONString(result);
		response(json);
	}
	
	/**
	 * 响应监控日志格式错误
	 * @throws Exception
	 */
	private void responseMonitorDateError() throws Exception{
		IFCResponseBean result = new IFCResponseBean();
		result.setResponseCode(IFCMonitorConstanst.MONITOR_RESPONSE_CODE_ERROR);
		result.setResponseMsg("monitorDate 参数异常！格式应为 【yyyyMMddHHmm-yyyyMMddHHmm】 或为【yyyyMMddHHmm】。");
		String json = JSON.toJSONString(result);
		response(json);
	}
	
	private Set<String> array2set(String[] typeArr){
		Set<String> typeSet = new HashSet<String>();
		if(typeArr!=null){
			for (String s : typeArr) {
				if(IFCMonitorUtils.isNotBlank(s)){
					typeSet.add(s);
				}
			}
		}
		return typeSet;
	}
	

	/**
	 * 验证日期格式
	 * 
	 * @param dateStr
	 * @return
	 */
	private boolean validateDate(String dateStr) {
		if (dateStr.length() != 12) {
			return false;
		}
		try {
			Long.parseLong(dateStr);
		} catch (Exception e) {
			return false;
		}
		return true;
	}

}
